#region  == Copyright == 
// =====================================================================
//  Microsoft Consulting Services France - Aymeric Mouillé - 2013
//  Projet     : CRM Solution Management Tool
//  Fichier    : SolutionGridControl.cs (30/04/2013 16:50)
//  
//  Copyright (C) Microsoft Corporation.  All rights reserved.
// =====================================================================
#endregion

namespace CRM.Solution.Management.Tool.Controls
{
    #region  == Using == 
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Windows.Forms;

    using Microsoft.Crm.Sdk.Messages;
    using Microsoft.Xrm.Sdk.Query;

    #endregion

    /// <summary>
    /// </summary>
    public partial class SolutionGridControl : UserControl
    {
        /// <summary>
        /// </summary>
        private readonly BackgroundWorker BgWorkerPublish;

        /// <summary>
        /// </summary>
        private readonly BackgroundWorker BgWorkerSolutions;

        private readonly BackgroundWorker BgWorkerDelete;

        /// <summary>
        /// </summary>
        private List<SolutionItem> SolutionItems;

        #region Main Form
        /// <summary>
        /// Gets the main form.
        /// </summary>
        /// <value>
        /// The main form.
        /// </value>
        public MainForm MainForm
        {
            get
            {
                return (MainForm)Parent.Parent.Parent;
            }
        }
        #endregion

        #region = Constructor =
        /// <summary>
        /// </summary>
        public SolutionGridControl()
        {
            InitializeComponent();
            BgWorkerSolutions = new BackgroundWorker();
            BgWorkerPublish = new BackgroundWorker();
            BgWorkerDelete = new BackgroundWorker();
        }
        #endregion

        #region Load Control
        /// <summary>
        /// </summary>
        public void LoadControl()
        {
            BgWorkerSolutions.DoWork += BgWorkerSolutionsOnDoWork;
            BgWorkerSolutions.RunWorkerCompleted += BgWorkerSolutionsOnRunWorkerCompleted;
            if (!BgWorkerSolutions.IsBusy)
            {
                MainForm.UpdateStripStatus("Loading, please wait ...");
                BgWorkerSolutions.RunWorkerAsync();
            }
        }
        #endregion

        #region Bg Worker Solutions On Do Work
        /// <summary>
        /// Bgs the worker jobs on do work.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="doWorkEventArgs">
        /// The <see cref="DoWorkEventArgs" /> instance containing the event data.
        /// </param>
        private void BgWorkerSolutionsOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
        {
            GetAllJobs();
        }
        #endregion

        #region Bg Worker Solutions On Run Worker Completed
        /// <summary>
        /// Bgs the worker jobs on run worker completed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="runWorkerCompletedEventArgs">
        /// The <see cref="RunWorkerCompletedEventArgs" /> instance containing the event data.
        /// </param>
        private void BgWorkerSolutionsOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
        {
            if (SolutionItems == null)
            {
                return;
            }
            if (SolutionItems.Count > 0)
            {
                dgvSolutions.DataSource = SolutionItems.ToList();
            }
            MainForm.UpdateStripStatus(string.Format("{0} solution(s) loaded!", SolutionItems.Count), 100);
            MainForm.CanTryAgain(SolutionItems.Count == 0);
        }
        #endregion

        #region Get All Jobs
        /// <summary>
        /// Gets all jobs.
        /// </summary>
        private void GetAllJobs()
        {
            SolutionItems = new List<SolutionItem>();

            MainForm.UpdateStripStatus("Querying for solutions ...");
            var query = new QueryExpression("solution") { ColumnSet = new ColumnSet(true) };

            try
            {
                var response = MainForm.OrganizationService.RetrieveMultiple(query);
                MainForm.UpdateStripStatus("Processing results ...");
                foreach (var solution in response.Entities)
                {
                    var solutionItem = new SolutionItem();
                    solutionItem.Id = solution.Id;
                    solutionItem.Name = solution.Attributes["uniquename"].ToString();
                    solutionItem.Type = ((bool)solution.Attributes["ismanaged"]) ? "Gérée" : "Non gérée";
                    solutionItem.Version = solution.Attributes["version"].ToString();
                    solutionItem.CreatedOn = solution.Attributes["createdon"].ToString();
                    solutionItem.ModifiedOn = solution.Attributes["modifiedon"].ToString();
                    solutionItem.InstalledOn = solution.Attributes["installedon"].ToString();
                    SolutionItems.Add(solutionItem);
                }
            }
            catch (Exception ex)
            {
                MainForm.UpdateStripStatus(string.Format("Failed to retrieve results! ({0})", ex.Message));
                if (MessageBox.Show(ex.Message, "Error", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error) == DialogResult.Retry)
                {
                    GetAllJobs();
                }
            }
        }
        #endregion

        #region Publish Completed
        /// <summary>
        /// </summary>
        /// <param name="sender">
        /// </param>
        /// <param name="e">
        /// </param>
        private void Publish_Completed(object sender, RunWorkerCompletedEventArgs e)
        {
            MainForm.UpdateStripStatus("Publishing completed!", 100);
        }
        #endregion

        #region Publish Do Work
        /// <summary>
        /// </summary>
        /// <param name="sender">
        /// </param>
        /// <param name="e">
        /// </param>
        private void Publish_DoWork(object sender, DoWorkEventArgs e)
        {
            var publishRequest = new PublishAllXmlRequest();
            MainForm.OrganizationService.Execute(publishRequest);
        }
        #endregion

        #region Btn Delete Click
        /// <summary>
        /// </summary>
        /// <param name="sender">
        /// </param>
        /// <param name="e">
        /// </param>
        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (dgvSolutions.SelectedRows.Count == 1)
            {
                var solutionItem = (SolutionItem)dgvSolutions.SelectedRows[0].DataBoundItem;
                if (MessageBox.Show(string.Format("Delete {0}?", solutionItem.Name), "Delete solution", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    BgWorkerDelete.DoWork += BgWorkerDelete_DoWork;
                    BgWorkerDelete.RunWorkerCompleted += BgWorkerDelete_RunWorkerCompleted;

                    MainForm.UpdateStripStatus("Deleting solution " + solutionItem.Name + "...");
                    BgWorkerDelete.RunWorkerAsync(solutionItem.Id);
                }
            }
        }
        #endregion

        #region Bg Worker Delete Do Work
        /// <summary>
        /// Handles the DoWork event of the BgWorkerDelete control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">
        /// The <see cref="DoWorkEventArgs" /> instance containing the event data.
        /// </param>
        private void BgWorkerDelete_DoWork(object sender, DoWorkEventArgs e)
        {
            Guid solutionId = (Guid)e.Argument;
            MainForm.OrganizationService.Delete("solution", solutionId);
        }
        #endregion

        #region Bg Worker Delete Run Worker Completed
        /// <summary>
        /// Handles the RunWorkerCompleted event of the BgWorkerDelete control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">
        /// The <see cref="RunWorkerCompletedEventArgs" /> instance containing the event data.
        /// </param>
        private void BgWorkerDelete_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MainForm.UpdateStripStatus("Solution removed!", 100);
            LoadControl();
        }
        #endregion

        #region Btn Export Click
        /// <summary>
        /// </summary>
        /// <param name="sender">
        /// </param>
        /// <param name="e">
        /// </param>
        private void btnExport_Click(object sender, EventArgs e)
        {
            if (dgvSolutions.SelectedRows.Count == 1)
            {
                var solutionItem = (SolutionItem)dgvSolutions.SelectedRows[0].DataBoundItem;
                SolutionExport solutionExport = new SolutionExport(MainForm, solutionItem);
                solutionExport.Show();
            }
        }
        #endregion

        #region Btn Import Click
        /// <summary>
        /// </summary>
        /// <param name="sender">
        /// </param>
        /// <param name="e">
        /// </param>
        private void btnImport_Click(object sender, EventArgs e)
        {
            MainForm.CurrentSolutionImportJobId = Guid.Empty;
            SolutionImport solutionImport = new SolutionImport(MainForm);
            solutionImport.Show();
        }
        #endregion

        #region Btn Publish Click
        /// <summary>
        /// </summary>
        /// <param name="sender">
        /// </param>
        /// <param name="e">
        /// </param>
        private void btnPublish_Click(object sender, EventArgs e)
        {
            BgWorkerPublish.DoWork += Publish_DoWork;
            BgWorkerPublish.RunWorkerCompleted += Publish_Completed;
            if (!BgWorkerPublish.IsBusy)
            {
                MainForm.UpdateStripStatus("Publishing, please wait ...");
                BgWorkerPublish.RunWorkerAsync();
            }
        }
        #endregion
    }
}
